package com.atchangsha.system.service.impl;

import com.atchangsha.system.common.utils.Result;
import com.atchangsha.system.constant.CustomerConstants;
import com.atchangsha.system.dto.CusCouponDTO;
import com.atchangsha.system.dto.DisCountDTO;
import com.atchangsha.system.dto.PhoneDto;
import com.atchangsha.system.entity.*;
import com.atchangsha.system.service.*;
import com.atchangsha.system.vo.CustomerPointVO;
import com.atchangsha.system.vo.DisCountVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atchangsha.system.common.utils.PageUtils;
import com.atchangsha.system.common.utils.Query;
import com.atchangsha.system.dao.CustomerDao;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

@Service("customerService")
@Slf4j
public class CustomerServiceImpl extends ServiceImpl<CustomerDao, CustomerEntity> implements CustomerService {

    @Resource
    private PointService pointService;

    @Resource
    private CustomerService customerService;

    @Resource
    private DiscountRulesService discountRulesService;
    @Resource
    private CouponService couponService;
    @Resource
    private CouponNumberService couponNumberService;
    @Resource
    private CustomerCouponRelationService customerCouponRelationService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        LambdaQueryWrapper<CustomerEntity> wrapper = new LambdaQueryWrapper<>();
        IPage<CustomerPointVO> voiPage = new Page<>();
        // 获取需要模糊查询的会员信息
        String key = (String) params.get("key");
        // 判断key是否为null
        if (!StringUtils.isEmpty(key)) {
            wrapper.like(CustomerEntity::getName, key).or()
                    .like(CustomerEntity::getPhone, key);
        }

        // 分页查询数据
        IPage<CustomerEntity> page = this.page(
                new Query<CustomerEntity>().getPage(params),
                wrapper
        );
        // 获取实体
        List<CustomerEntity> list = page.getRecords();
        // 对数据进行组合
        List<CustomerPointVO> collect = list.stream().map(item -> {
            // 返回的VO
            CustomerPointVO customerPointVO = new CustomerPointVO();
            // 获取point信息
            Long pointId = item.getPointId();
            PointEntity pointEntity = pointService.getById(pointId);
            // 会员的总积分
            long pointSum = pointEntity.getPointSum();
            // 获取会员等级
            List<DiscountRulesEntity> discountRulesEntities = discountRulesService.list();
            Long point = 0L;
            DiscountRulesEntity start = discountRulesEntities.get(0);
            DiscountRulesEntity end = discountRulesEntities.get(discountRulesEntities.size() - 1);
            for (int i = 0; i < discountRulesEntities.size(); i++) {
                DiscountRulesEntity entity = discountRulesEntities.get(i);
                if (start.getPoint() > pointSum) {
                    customerPointVO.setLevelName(start.getLevelName());
                    break;
                }
                if (end.getPoint() < pointSum) {
                    customerPointVO.setLevelName(end.getLevelName());
                    break;
                }
                if (point < pointSum && pointSum <= entity.getPoint()) {
                    customerPointVO.setLevelName(entity.getLevelName());
                }
                // 获取前一个等级的范围值
                point = entity.getPoint();
            }
            // 赋值
            BeanUtils.copyProperties(pointEntity, customerPointVO);
            BeanUtils.copyProperties(item, customerPointVO);
            return customerPointVO;
        }).collect(Collectors.toList());

        //赋值分页信息
        BeanUtils.copyProperties(page, voiPage);
        voiPage.setRecords(collect);

        return new PageUtils(voiPage);
    }

    @Override
    @Transactional
    public Result getMember(DisCountDTO disCountDTO) {
        log.info("disCountDTO:{}", disCountDTO);
        // 电话号码
        String phone = disCountDTO.getPhone();
        LambdaQueryWrapper<CustomerEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerEntity::getPhone, phone);
        CustomerEntity customerEntity = customerService.getOne(wrapper);
        if (customerEntity == null) {
            return Result.fail(CustomerConstants.CustomerEnum.PHONE_IS_NULL);
        }
        //原价
        Double price = disCountDTO.getPrice();
        // 积分表id
        Long pointId = customerEntity.getPointId();
        PointEntity pointEntity = pointService.getById(pointId);
        if (pointEntity == null) {
            return Result.fail(CustomerConstants.CustomerEnum.NOT_HAS_POINT);
        }
        // 返回的VO
        DisCountVO disCountVO = new DisCountVO();
        // 会员的总积分
        long pointSum = pointEntity.getPointSum();
        LambdaQueryWrapper<DiscountRulesEntity> queryWrapper = new LambdaQueryWrapper<>();
        DiscountRulesEntity discountRulesEntity = null;
        double f;
        if (pointSum < 1000) {
            disCountVO.setLevelName("普通会员");
            // 应付price
            f = price * 1.0;
        } else {
            // 获取会员等级
            List<DiscountRulesEntity> discountRulesEntities = discountRulesService.list(queryWrapper);
            discountRulesEntity = discountRulesEntities.get(discountRulesEntities.size() - 1);
            disCountVO.setLevelName(discountRulesEntity.getLevelName());
            // 应付price
            f = price * discountRulesEntity.getDiscount();
        }
        BigDecimal bg = new BigDecimal(f);
        disCountVO.setPrice(bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        // 折扣优惠
        BigDecimal bg1 = new BigDecimal(price - f);
        disCountVO.setDisCount(bg1.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        return Result.ok(CustomerConstants.CustomerEnum.GET_MEMBER_LEVEL_AND_DISCOUNT_SUCCESS).setResult(disCountVO);
    }

    @Override
    @Transactional
    public Boolean registerMember(PhoneDto phoneDto) {
        // 创建会员
        CustomerEntity customerEntity = new CustomerEntity();
        customerEntity.setPhone(phoneDto.getPhone());
        customerEntity.setName(phoneDto.getName());

        //创建积分
        PointEntity pointEntity = new PointEntity();

        boolean flag = pointService.save(pointEntity);

        if (flag) {
            customerEntity.setPointId(pointEntity.getId());
        }
        return this.save(customerEntity);
    }

    @Transactional
    @Override
    public Result getCoupon(CusCouponDTO cusCouponDTO) {
        // 根据电话获取用户信息
        CustomerEntity customerEntity = customerService.getOne(new LambdaQueryWrapper<CustomerEntity>().eq(CustomerEntity::getPhone, cusCouponDTO.getPhone()));
        if (customerEntity == null) {
            return Result.fail(CustomerConstants.CustomerEnum.GET_MEMBER_FAIL);
        }
        // 将用户id和优惠券id进行绑定
        CustomerCouponRelationEntity relationEntity = new CustomerCouponRelationEntity();
        relationEntity.setCouponId(cusCouponDTO.getCouponId());
        relationEntity.setCustomerId(customerEntity.getId());
        if (!customerCouponRelationService.save(relationEntity)) {
            return Result.fail(CustomerConstants.CustomerEnum.SAVE_COUPON_CUSTOMER_FAIL);
        }
        //将优惠券数量减少
        CouponNumberEntity couponNumberEntity = couponNumberService.getOne(new LambdaQueryWrapper<CouponNumberEntity>().eq(CouponNumberEntity::getCouponId, cusCouponDTO.getCouponId()));
        Integer number = couponNumberEntity.getNumber();
        if (number <= 0) {
            return Result.fail(CustomerConstants.CustomerEnum.GET_COUPON_FAIL);
        }
        number -= 1;
        couponNumberEntity.setNumber(number);
        if(!couponNumberService.updateById(couponNumberEntity)){
            return Result.fail(CustomerConstants.CustomerEnum.UPDATE_COUPON_NUMBER_FAIL);
        }
        return Result.ok(CustomerConstants.CustomerEnum.GET_COUPON_SUCCESS);
    }

}